using System;
using dnAnalytics.Statistics.Distributions;
using NUnit.Framework;

namespace dnAnalytics.Tests.Statistics.Distributions
{
    [TestFixture]
    public class NormalGammaTests
    {
        private const double mAcceptableError = 1e-12;

        [Test]
        public void NormalGammaTest()
        {
            NormalGamma ng = new NormalGamma(10.0, 1.0, 2.0, 2.0);

            Assert.AreEqual(10.0, ng.Mean.Mean, mAcceptableError);
            Assert.AreEqual(1.0, ng.Mean.Precision, mAcceptableError);
            Assert.AreEqual(10.0, ng.Mode.Mean, mAcceptableError);
            Assert.AreEqual(1.0, ng.Mode.Precision, mAcceptableError);
            Assert.AreEqual(10.0, ng.Median.Mean, mAcceptableError);
            Assert.AreEqual(1.0, ng.Median.Precision, mAcceptableError);

            double d1 = ng.Density(2.0, 2.0);
            double d2 = ng.Density(new MeanPrecisionPair(2.0, 2.0));
            double ld1 = ng.DensityLn(2.0, 2.0);
            double ld2 = ng.DensityLn(new MeanPrecisionPair(2.0, 2.0));
            Assert.AreEqual(d1, d2, mAcceptableError);
            Assert.AreEqual(d1, System.Math.Exp(ld1), mAcceptableError);
            Assert.AreEqual(d1, System.Math.Exp(ld2), mAcceptableError);

            var s = ng.Sample();
            var ss = ng.Sample(5);
        }

        [TestCase(1.0, -1.3, 2.0, 2.0, ExpectedException = typeof(ArgumentOutOfRangeException))]
        [TestCase(1.0, 1.0, -1.0, 1.0, ExpectedException = typeof(ArgumentOutOfRangeException))]
        [TestCase(1.0, 1.0, 1.0, -1.0, ExpectedException = typeof(ArgumentOutOfRangeException))]
        public void InvalidParams(double a, double b, double c, double d)
        {
            var nb = new NormalGamma(a, b, c, d);
        }

        [Test]
        public void GetSetRNG()
        {
            NormalGamma ng = new NormalGamma(10.0, 1.0, 2.0, 2.0);

            // Try getting the random number generator.
            System.Random rnd = ng.RandomNumberGenerator;
            // Try setting the random number generator.
            ng.RandomNumberGenerator = new System.Random();
        }
    }
}